#include "plugin.h"
#include <stack>
#include <list>
#include <vector>
#include <map>
#include <algorithm>
#include <unistd.h>

struct AlgFindFnt final: public AlgFind {
	static AlgFind* creater() {
		return new AlgFindFnt{};
	}
	// params
	void setParams(const std::vector<ParamValue>& params) override {
	}
	std::vector<ParamValue> getParams() const override {
		std::vector<ParamValue> vl;
		return vl;
	}
	AlgFindFnt(): AlgFind{} { }

	// data
	std::vector<int64_t> idxes{};

	void find(const Position& p, Graph gr, Path* pth) override {
		double x=p.point.x();
		double y=p.point.y();
		double z=p.point.z();
		idxes.clear();
		for(double dz=-20; dz<20; dz+=2) {
			for(double dy=-20; dy<20; dy+=2) {
				for(double dx=-20; dx<20; dx+=2) {
					auto i=xyzf2index<0>(x+dx, y+dy, z+dz);
					if(i>=0) {
						if(xfunc<0>(cube<0>(i))>.5) {
							idxes.push_back(i);
						}
					}
				}
			}
		}
		//
		//
		while(sync(1000)) {
			usleep(1000);
		}
		pth->points.clear();
	}
	std::vector<int32_t> getUpdate() const override {
		std::vector<int32_t> data{};
			for(auto i: idxes) {
			double x, y, z;
			index2xyzf<0>(i, &x, &y, &z);
			Point p(x, y, z);
			data.push_back(p._x);
			data.push_back(p._y);
			data.push_back(p._z);
			}
		return data;
	}
};

static void fnt_load(std::vector<AlgorithmInfo*>& algs, std::vector<GraphReaderInfo*>& readers) {
	auto algfind=new AlgInfo<AlgFind>{"FNT", 80,
		"The FNT method of finding putative paths based on Dijkstra's algorithm.",
		{
		},
		AlgFindFnt::creater};
	algs.push_back(algfind);
}

static void fnt_unload() {
}

FNT_PLUGIN("FNT", fnt_load, fnt_unload, "FNT algorithm for finding putative paths.");
